
package flp.gui.view.annealing;

import java.awt.Color;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.FixedMillisecond;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYDataset;

/** 
 * Klasa przedstawiajaca wykres rysowany przy optymalizacji
 * algorytmem stymulowanego wyzarzania.
 * 
 * @author Mateusz Pytel
 */
public class AnnealingChart {
        
        /** Obiekt zarzadzajacy powiazaniem wartosci na osiach - dla najlepszego rozwiazania.*/
        private TimeSeries timeSeriesBest;
        
        /** Wlasciwa instancja wykresu */
        private JFreeChart mainChart;
        
        /** Panel na ktorym rysowany jest wykres */
        private ChartPanel chartPanel;
        
        /** Flaga sygnalizujaca zaznaczenie pierwszej danej na wykresie */
        private boolean firstMark;
        
        /** Licznik wspomagajacy skalowanie wykresu */
        private int rangeCount;
    
        /** Kolor tla okna */
        private static final Color BACKGROUND_COLOR=Color.WHITE;
        
        /** Kolor tla wykresu */
        private static final Color PLOT_BACKGROUND_COLOR = Color.LIGHT_GRAY;
        
        /** Kolor linii siatki */
        private static final Color GRIDLINE_COLOR = Color.WHITE;
        
        /** Poczatkowy zakres osi X [ms] */
        private static final long RANGE_AXIS_LENGTH = 30000;
        
        
        /**
         * Konstruktor klasy 
         * 
         * @param chartTitle tytul wykresu (null = brak tytulu)
         */
        AnnealingChart(String chartTitle){
            timeSeriesBest = new TimeSeries("Najlepszy koszt",FixedMillisecond.class); 
            TimeSeriesCollection bestTimeSeriesCollection = new TimeSeriesCollection(timeSeriesBest);
            
            mainChart = createChart(bestTimeSeriesCollection, 
                    "");
            chartPanel = new ChartPanel(mainChart);
            mainChart.setBackgroundPaint(BACKGROUND_COLOR);
            chartPanel.setFillZoomRectangle(false);
            XYPlot plot = mainChart.getXYPlot();
            plot.setBackgroundPaint(PLOT_BACKGROUND_COLOR);
            plot.setDomainGridlinePaint(GRIDLINE_COLOR);
            plot.setRangeGridlinePaint(GRIDLINE_COLOR);
            ValueAxis axis = plot.getDomainAxis();
            axis.setAutoRange(true);
            axis.setFixedAutoRange(RANGE_AXIS_LENGTH);  // 60 seconds
            axis.setLowerMargin(0);
            plot.setRenderer(1,new XYLineAndShapeRenderer(true,false));
            rangeCount=1;
            mainChart.removeLegend();
        }

    /** 
     * Metoda pobierajaca panel na ktorym rysowany jest wykres.
     * 
     * @return Panel zawierajacy wykres.
     */        
    public ChartPanel getChartPanel() {
        return chartPanel;
    }
        
    /**
     * Metoda zaznaczajaca na wykresie dany punkt.
     * 
     * @param topCost Wartosc punku do zaznaczenia.
     * @param timeElapsed Wspolrzedna x'owa (jednostka czasu).
     */
    public void markData(int topCost, int timeElapsed){
        if(timeElapsed > rangeCount*RANGE_AXIS_LENGTH){
            rangeCount++;
            mainChart.getXYPlot().getDomainAxis().setFixedAutoRange(rangeCount*RANGE_AXIS_LENGTH);
        }
        
        timeSeriesBest.add(new FixedMillisecond(timeElapsed-3600000),topCost);

        if (firstMark){
            firstMark=false;
            mainChart.getXYPlot().getRangeAxis().setAutoRange(true);
        }
    }
        
    /**
     * Konstruktor instancji wykresu wlasciwego.
     * 
     * @param dataset Klasa operujaca na danych.
     * @param title Tytul wykresu.
     * @return Nowy obiekt reprezentujacy wykres.
     */
    private JFreeChart createChart(XYDataset dataset, String title) {
        final JFreeChart result = ChartFactory.createTimeSeriesChart(
            title, 
            "Czas trwania optymalizacji", 
            "Koszt",
            dataset, 
            true, 
            true, 
            false
    );
        firstMark=true;
        final XYPlot plot = result.getXYPlot();
        ValueAxis axis = plot.getDomainAxis();
        axis.setAutoRange(true);
        axis.setFixedAutoRange(60000.0);  // 60 seconds
        axis = plot.getRangeAxis();
        axis.setRange(0.0, 200.0); 
        return result;
    }
      
    /**
     * Metoda do ustawiania tytulu wykresu. 
     * 
     * @param newTitle Nowy tytul wykresu.
     */
    public void setTitle(String newTitle){
        mainChart.setTitle(newTitle);
    }
}
